home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / PCGPEV10.ZIP / KEYBOARD.TXT < prev    next >
Text File  |  1994-05-10  |  11KB  |  244 lines

  1.  
  2.                      ┌──────────────────────────┐
  3.                      │ Programming the Keyboard │
  4.                      └──────────────────────────┘
  5.  
  6.                  Written for the PC-GPE by Mark Feldman
  7.               e-mail address : u914097@student.canberra.edu.au
  8.                                myndale@cairo.anu.edu.au
  9.  
  10.              ┌───────────────────────────────────────────┐
  11.              │      THIS FILE MAY NOT BE DISTRIBUTED     │
  12.              │ SEPARATE TO THE ENTIRE PC-GPE COLLECTION. │
  13.              └───────────────────────────────────────────┘
  14.  
  15.  
  16. ┌────────────┬───────────────────────────────────────────────────────────────
  17. │ Disclaimer │
  18. └────────────┘
  19.  
  20. I assume no responsibility whatsoever for any effect that this file, the
  21. information contained therein or the use thereof has on you, your sanity,
  22. computer, spouse, children, pets or anything else related to you or your
  23. existance. No warranty is provided nor implied with this information.
  24.  
  25. ┌──────────┬─────────────────────────────────────────────────────────────────
  26. │ Overview │
  27. └──────────┘
  28.  
  29. The operation of the keyboard is really quite simple. Every time a key
  30. is pressed or released an interrupt 9 is generated, and reading the value
  31. from port 60h tells you what happened.
  32.  
  33. ┌────────────────────────────┬───────────────────────────────────────────────
  34. │ Decoding the Keyboard Byte │
  35. └────────────────────────────┘
  36.  
  37. So let's say you've installed an interrupt handler to handle all keyboard
  38. events and when an interrupt is generated your handler reads the byte from
  39. port 60h. What now?
  40.  
  41. Well..each key on the keyboard has an associated scan code which is contained
  42. in the lower 7 bits of the byte. The most significant bit (ie bit 7) tells
  43. you what was actually done, 0 = key was just pressed, 1 = key was just
  44. released. If someone had just pressed the ESC key for instance, the port will
  45. show a value of 1 (1 is the ESC key's scan code). If they hold their finger
  46. on the button the keyboard will keep generating interrupt 9's and each
  47. time the port will still show a value of 1. When the person releases the key
  48. a final interrupt will be generated and the port will return 129 (1 + 128,
  49. since the high bit will be set indicating the person has released the key).
  50.  
  51. Well...it's almost this simple. Some keys are "extended" keys. When an
  52. extended key is pressed an interrupt is generated and the keyboard port
  53. will return a value of 224 (E0h). This means that an extended key was pressed
  54. and it's *extended* scan code will be available during the *next* interrupt.
  55. Note that the left control key has a scan code of 29, while the *right*
  56. control key has an *extended* scan code of 29. The same applies to the alt
  57. keys and the arrow keys (keypad arrows vs the other ones).
  58.  
  59. It would be nice if all keys were created equal and we could just throw away
  60. the 224 extended bytes and handle all the other bytes normally. Unfortunately
  61. there are two buttons which on my machine at least (and others I have tested)
  62. do some really weird stuff:
  63.  
  64. PrtScn
  65. ──────
  66. Pressing this button will send *2* extended characters to the handler, 42
  67. and 55, so the actual byte sequence will be 224, 42, 224, 55. (Also note
  68. that the left shift key has a regular scan code of 42, so there goes our
  69. idea of just throwing 224's away). Only the extended 55's are sent during
  70. auto-repeat. When the key is released, the two are sent again with the high
  71. bits set (224, 170, 224, and 183). If any of the shift or control keys are
  72. being held down when the PrtScn button is pressed then only the (224, 55) is
  73. sent when the key is pressed and only the (224, 183) is sent when it's
  74. released. If the alt key is being held down (System Request) then the key
  75. behaves like an ordinary key with scan code 84. The practical upshot of all
  76. this is that the handlers you write to handle normal keys and extended keys
  77. will work fine with all the different PrtScn combinations (although a program
  78. would have to check normal key 84 *AND* extended key 55 in order to determine
  79. if the key is currently being pressed).
  80.  
  81. Pause/Break
  82. ───────────
  83. Welcome to hell. If you press this key while either of the the control keys
  84. are being held down, it will behave like extended key 70, at all other times
  85. it will send the following bytes: (225, 29, 69, 225, 157, 197). Holding the
  86. key down does not result in autorepeat. Taking your finger off the key does
  87. not send any extra bytes, they appear to be sent after the "key down" bytes
  88. when you first press the key. Notice that 225 isn't 224, so our normal
  89. extended character handler will not take care of this. My personal theory is
  90. that while a scan code of 224 (E0h) means there is 1 more character
  91. following, a scan code of 225 (E1h) means there are *2* more following. I've
  92. seen a number of keyboard handler libraries and they all seem to overlook
  93. this key. So why not be the first kid on your block to have a keyboard
  94. handler which properly supports the Pause/Break key? CHECK IT OUT!!
  95.  
  96. ┌───────────────────┬────────────────────────────────────────────────────────
  97. │ Writing a Handler │
  98. └───────────────────┘
  99.  
  100. Writing a keyboard handler is fairly straightforward. This section will
  101. show how to do it in Pascal (you C and asm programmers would probably already
  102. know this stuff anyway).
  103.  
  104. First we'll declare a few things we'll need:
  105.  
  106. const KEYBOARDINTR = 9;
  107.       KEYBOARDPORT = $60;
  108.  
  109. var BIOSKeyboardHandler : procedure;
  110.     CallBIOSHandler : boolean;
  111.  
  112. The CallBIOSHandler variable will be initialised by the calling program. If
  113. we also want the BIOS handler to process all keystrokes then this variable
  114. must be set to true.
  115.  
  116. Next we need to store the value of the current handler and set up own our
  117. own one. We'll use a procedure called KeyboardHandler to handle the actual
  118. interrupt.
  119.  
  120. CallBIOSHandler := false; { ...or set it to true if you want. }
  121. GetIntVec(KEYBOARDINTR, @BIOSKeyboardHandler);
  122. SetIntVec(KEYBOARDINTR, Addr(KeyboardHandler));
  123.  
  124. Ok, so everything is now set up and our handler will now be able to process
  125. all keyboard events. The actual interrupt handler could look like this:
  126.  
  127. {$F+}
  128. procedure KeyboardHandler(Flags, CS, IP, AX, BX, CX, DX,
  129.                           SI, DI, DS, ES, BP: Word);
  130. interrupt;
  131. var key : byte;
  132. begin
  133.  
  134.   key := Port[KEYBOARDPORT];
  135.  
  136.   { PROCESS THE KEYSTROKE HERE }
  137.  
  138.   if CallBIOSHandler then
  139.  
  140.   { Call the BIOS keyboard handler if the calling program wants us to }
  141.     begin
  142.       asm pushf end;
  143.       BIOSKeyboardHandler;
  144.     end
  145.  
  146.   { Otherwise just acknowledge the interrupt }
  147.   else Port[$20] := $20;
  148. end;
  149. {$F-}
  150.  
  151.  
  152. When the program is finished we can set the old keyboard handler again:
  153.  
  154. SetIntVec(KEYBOARDINTR, @BIOSKeyboardHandler);
  155.  
  156. ┌───────────────────┬────────────────────────────────────────────────────────
  157. │ A Word of Warning │
  158. └───────────────────┘
  159.  
  160. When I was writing a simple handler to test the info in this file I did
  161. something REALLY stoopid which I would like to share with the world. I
  162. thought that my program was stuffing the keyboard up because when I exited
  163. the program my editor (Borland Pascal 7.0) would act as though the control
  164. button was being held down (I'm sure some of you have already started
  165. laughing by now). I had to press it after each time I ran the program
  166. just to sort it out. After spending a few hours looking all over the place
  167. for info on what could possibly be wrong I realised what I was doing. I was
  168. pressing CTRL-F9 to compile the program which would also immediately make it
  169. run and I was releasing the control key when my program was running, ie the
  170. regular BIOS handler was not getting the control key's "key up" command and
  171. still thought it was being held down when my program returned control to
  172. it. Moron.....
  173.  
  174. ┌────────────┬───────────────────────────────────────────────────────────────
  175. │ Scan Codes │
  176. └────────────┘
  177.  
  178. The following is a list of all the regular key scan codes in numerical
  179. order:
  180.  
  181. Scan                                   Scan
  182. Code Key                               Code Key
  183. ──────────────────────────             ──────────────────────────
  184.  1   ESC                               44   Z
  185.  2   1                                 45   X
  186.  3   2                                 46   C
  187.  4   3                                 47   V
  188.  5   4                                 48   B
  189.  6   5                                 49   N
  190.  7   6                                 50   M
  191.  8   7                                 51   , <
  192.  9   8                                 52   . >
  193. 10   9                                 53   / ?
  194. 11   0                                 54   RIGHT SHIFT
  195. 12   - _                               55   *            (KEYPAD)
  196. 13   = +                               56   LEFT ALT
  197. 14   BACKSPACE                         57   SPACEBAR
  198. 15   TAB                               58   CAPSLOCK
  199. 16   Q                                 59   F1
  200. 17   W                                 60   F2
  201. 18   E                                 61   F3
  202. 19   R                                 62   F4
  203. 20   T                                 63   F5
  204. 21   Y                                 64   F6
  205. 22   U                                 65   F7
  206. 23   I                                 66   F8
  207. 24   O                                 67   F9
  208. 25   P                                 68   F10
  209. 26   [ {                               69   NUMLOCK      (KEYPAD)
  210. 27   ] }                               70   SCROLL LOCK
  211. 28   ENTER (RETURN)                    71   7 HOME       (KEYPAD)
  212. 29   LEFT CONTROL                      72   8 UP         (KEYPAD)
  213. 30   A                                 73   9 PGUP       (KEYPAD)
  214. 31   S                                 74   -            (KEYPAD)
  215. 32   D                                 75   4 LEFT       (KEYPAD)
  216. 33   F                                 76   5            (KEYPAD)
  217. 34   G                                 77   6 RIGHT      (KEYPAD)
  218. 35   H                                 78   +            (KEYPAD)
  219. 36   J                                 79   1 END        (KEYPAD)
  220. 37   K                                 80   2 DOWN       (KEYPAD)
  221. 38   L                                 81   3 PGDN       (KEYPAD)
  222. 39   ; :                               82   0 INSERT     (KEYPAD)
  223. 40   ' "                               83   . DEL        (KEYPAD)
  224. 41   ` ~                               87   F11
  225. 42   LEFT SHIFT                        88   F12
  226.  
  227.  
  228. The following is a list of all the extended key scan codes in numerical
  229. order:
  230.  
  231. Scan                                   Scan
  232. Code Key                               Code Key
  233. ───────────────────────────────        ───────────────────────────────
  234. 28   ENTER        (KEYPAD)              75   LEFT         (NOT KEYPAD)
  235. 29   RIGHT CONTROL                      77   RIGHT        (NOT KEYPAD)
  236. 42   PRINT SCREEN (SEE TEXT)            79   END          (NOT KEYPAD)
  237. 53   /            (KEYPAD)              80   DOWN         (NOT KEYPAD)
  238. 55   PRINT SCREEN (SEE TEXT)            81   PAGE DOWN    (NOT KEYPAD)
  239. 56   RIGHT ALT                          82   INSERT       (NOT KEYPAD)
  240. 71   HOME         (NOT KEYPAD)          83   DELETE       (NOT KEYPAD)
  241. 72   UP           (NOT KEYPAD)         111   MACRO
  242. 73   PAGE UP      (NOT KEYPAD)
  243.  
  244.